<?php
/**
 * alltosun.com 微信支付控制器 index.php
 * ============================================================================
 * 版权所有 (C) 2009-2014 北京互动阳光科技有限公司，并保留所有权利。
 * 网站地址:   http://www.alltosun.com
 * ----------------------------------------------------------------------------
 * 许可声明：这是一个开源程序，未经许可不得将本软件的整体或任何部分用于商业用途及再发布。
 * ============================================================================
 * $Author: 李维 (liw@alltosun.com) $
 * $Date: 2014-9-12 下午12:55:05 $
 * $Id: index.php 94045 2014-11-27 01:49:43Z gougy $
*/

error_reporting(0);
if(ONDEV) {
    include MODULE_PATH."/openapi/config/weixindev_config.php";
} else {
    include MODULE_PATH."/openapi/config/weixin_config.php";
}
include MODULE_PATH."/openapi/helper/WxPayPubHelper/WxPayPubHelper.php";

//扫码支付
include MODULE_PATH."/openapi/helper/WxpayAPI_v3/lib/WxPay.Api.php";
include MODULE_PATH."/openapi/helper/WxpayAPI_v3/WxPay.NativePay.php";


class Action
{
    // 微信公众号身份的唯一标识。审核通过后，在微信发送的邮件中查看
    private $wx_appid;

    // 受理商ID，身份标识
    private $wx_mchid;

    // 商户支付密钥Key。审核通过后，在微信发送的邮件中查看
    private $wx_key;

    // JSAPI接口中获取openid，审核后在公众平台开启开发模式后可查看
    private $wx_appsecret;

    // 获取access_token过程中的跳转uri，通过跳转将code传入jsapi支付页面 此处没有用到
    private $wx_js_api_call_url;

    // 异步通知url设置
    private $wx_notify_url;

    // curl超时设置
    private $wx_curl_timeout;

    public function __construct()
    {
        $this->wx_appid           = WxPayConf_pub::APPID;
        $this->wx_mchid           = WxPayConf_pub::MCHID;
        $this->wx_key             = WxPayConf_pub::KEY;
        $this->wx_appsecret       = WxPayConf_pub::APPSECRET;
        $this->wx_js_api_call_url = WxPayConf_pub::JS_API_CALL_URL;
        $this->wx_notify_url      = WxPayConf_pub::NOTIFY_URL;
        $this->wx_curl_timeout    = WxPayConf_pub::CURL_TIMEOUT;
    }


    /**
     * 此处传递订单号，不同项目估计需要定义一下各自的body组织形式
     */
    public function __call($action = '', $param = array())
    {

        $openid   = '';
        $user_id  = user_helper::get_user_id();

        //$user_id  = 16;

        if(!$user_id) {
            return '支付失败：未登录用户';
        }
        if(in_mobile()) {
            if(!is_weixin()) {
                return '支付失败：请在微信端访问';
            }

            // 是否微信的账户，必须是微信账户才能支付啊，晕
            $openid_info = _uri('weixin_openid', array('user_id'=>$user_id));
            // $connect_info = _model('connect_weixin')->read(array('user_id' => $user_id));
            if (!$openid_info) {
                return '支付失败：请重新提交订单!';
            }

            if (isset($openid_info['open_id']) && $openid_info['open_id']) {
                $openid = $openid_info['open_id'];
            }

            if (!$openid) {
                return '微信授权失败：请重新提交订单!';
            }
        }
        

        // 订单ID
        $order_id    = Request::getParam('order_id', 0);

        //$order_id    = 1000011;

        if(!$order_id) {
            return '支付失败：订单参数错误';
        }

        $order_info = _uri('order', $order_id);

        if(!$order_info) {
            return '支付失败：没有此订单信息';
        }

        // 组装body
        if($order_info['progress'] != 1) {
            return '此订单未处于待支付状态，不能进行支付';
        }

        // 寻找快照表，快照ID
        //$order_relation_info = _model('order_relation')->read(array('order_id'=>$order_info['id']));
        $order_relation_info = _uri('order_relation', array('order_id'=>$order_info['id']));
        if (!$order_relation_info) {
            return '此订单已经失效，不能进行支付';
        }

        // 快照
        $goods_info = _uri('goods', $order_relation_info['goods_id']);
        if (!$goods_info) {
            return '此订单已经失效，不能进行支付';
        }

        $body = $goods_info['title'];

        $price = $order_info['price'];

        // 以分为单位
        $price = $price * 100;
        $attach = 'newbd';
        // 测试
        if (ONDEV)  $price = 1;

        if(!in_mobile()) {
            $notify = new NativePay();
            $input = new WxPayUnifiedOrder();
            $input->SetBody($body);
            $input->SetAttach($attach);
            //时间+1为PC 2为手机+NBD订单号
            $input->SetOut_trade_no(date('YmdH').'1'.$order_info['id']);
            $input->SetTotal_fee($price);
            $input->SetTime_start(date("YmdHis"));
            $input->SetTime_expire(date("YmdHis", time() + 600));
            $input->SetNotify_url($this->wx_notify_url);
            // $input->SetNotify_url("http://newbd.alltosun.net/WxpayAPI_php_v3/example/notify.php");
            $input->SetTrade_type("NATIVE");
            $input->SetProduct_id($goods_info['id']);
            $result = $notify->GetPayUrl($input);
            if($result['result_code'] != 'SUCCESS') {
                
            } else {
                $url = $result["code_url"];
                $qrcode_img = "http://paysdk.weixin.qq.com/example/qrcode.php?data=".$url;
                return array('info'=>'ok', 'img_url'=>$qrcode_img);
            }
            
        }


        $sign_info = array(
                'body'     => $body,
                'price'    => $price,
                //时间+1为PC 2为手机+NBD订单号
                'order_id' => date('YmdH').'2'.$order_info['id'],
                //'order_id' => uniqid(),
                'attach'   => $attach
        );

        //print_r($sign_info);exit;

        // echo $openid;exit;
        $package_str = $this->sign_package($openid, $sign_info);
        // return $package_str;
        // print_r($package_str);exit;
        return array(
                        'info'     => 'ok',
                        'info_url' => AnUrl('order/index'),
                        'pay_info' => $package_str
        );
    }


    /**
     * 签名package
     * @param int $time_expire 过期时间 默认15分钟 单位 分钟
     */
    private function sign_package($openid, $info, $time_expire = 15) {

        //return 'aaaa';
        $jsApi = new JsApi_pub();
        //$openid = 'oJCOTjqanhfaQqGBemSmLEX3C38o';

        // 使用统一支付接口
        $unifiedOrder = new UnifiedOrder_pub();

        // 商品描述
        $unifiedOrder->setParameter("openid",$openid);
        $unifiedOrder->setParameter("body", $info['body']);

        // 商户订单号
        $unifiedOrder->setParameter("out_trade_no", $info['order_id']);
        //echo $info['price'];
        //return $info['order_id'];
        // 总金额
        $unifiedOrder->setParameter("total_fee", $info['price']);
        // 通知地址
        $unifiedOrder->setParameter("notify_url",AnUrl('openapi/weixin/pay/notify'));
        // 交易类型
        $unifiedOrder->setParameter("trade_type","JSAPI");
        $unifiedOrder->setParameter("input_charset", "UTF-8");

        $prepay_id = $unifiedOrder->getPrepayId();

        //return $prepay_id;

        if(!$prepay_id) {
            throw new AnMessageException($unifiedOrder->err_msg);
        }
        // =========步骤3：使用jsapi调起支付============
        $jsApi->setPrepayId($prepay_id);

        $jsApiParameters = $jsApi->getParameters();

        return json_decode($jsApiParameters,true);
    }

    /**
     * 异步支付
     */
    public function notify()
    {
        // 使用通用通知接口
        $notify = new Notify_pub();
        // mail_helper::mail('353182225@qq.com', '微信支付异步notify', '');
        // 存储微信的回调
        $xml = $GLOBALS['HTTP_RAW_POST_DATA'];

        $notify->saveData($xml);

        // 验证签名，并回应微信。
        // 对后台通知交互时，如果微信收到商户的应答不是成功或超时，微信认为通知失败，
        // 微信会通过一定的策略（如30分钟共8次）定期重新发起通知，
        // 尽可能提高通知的成功率，但微信不保证通知最终能成功。
        if($notify->checkSign() == FALSE){

            // 返回状态码
            $notify->setReturnParameter("return_code","FAIL");

            // 返回信息
            $notify->setReturnParameter("return_msg","签名失败");

        }else{
            // 设置返回码
            $notify->setReturnParameter("return_code","SUCCESS");
        }

        //print_r($notify->data);return;

        // mail_helper::mail('353182225@qq.com', '微信支付异步返回信息', var_export($notify->data, true));

        // 订单号
        $order_id         = $notify->data['out_trade_no'];
        // 订单金额
        $price            = $notify->data['total_fee'];

        // 微信订单号
        $transaction_id   = $notify->data['transaction_id'];
        $finish_time      = $notify->data['time_end'];
        $finish_time      = date('Y-m-d H:i:s', strtotime($finish_time));

        // 验签
        if($notify->checkSign() == TRUE) {
            //mail_helper::mail('245629560@qq.com', 'order_id', $order_id);
            if ($notify->data["return_code"] == "FAIL") {

                // 返回状态码
                $notify->setReturnParameter("return_code","FAIL");

                // 返回信息
                $notify->setReturnParameter("return_msg","签名失败");

                // 此处应该更新一下订单状态，商户自行增删操作
                //_widget('email')->mail('付款通知异常(weixin_h5)', 'paySign  is fail'.$order_no);

            } elseif ($notify->data["result_code"] == "FAIL"){

                // 返回状态码
                $notify->setReturnParameter("return_code","FAIL");

                // 返回信息
                $notify->setReturnParameter("return_msg","签名失败");

                // 此处应该更新一下订单状态，商户自行增删操作
                //_widget('email')->mail('付款通知异常(weixin_h5)', 'paySign  is fail'.$order_no);

            } else {
                // 此处应该更新一下订单状态，商户自行增删操作
                //mail_helper::mail('245629560@qq.com', '异步通知成功', $order_id);
                // 验证订单
                if(!$order_id) {
                    //mail_helper::mail('245629560@qq.com', '付款通知异常(weixin_h5)', 'order_id is empty'.$order_id);
                    //_widget('email')->mail('付款通知异常(weixin_h5)', 'order_id is empty'.$order_no);
                    exit('fail');
                }
                //201506300230252
                $order_id = substr($order_id, 11);
                // mail_helper::mail('353182225@qq.com', '付款通知order_id(weixin_h5)', 'order_id is'.$order_id);
                $order_info = _uri('order', $order_id);
                if(!$order_info) {
                    mail_helper::mail('353182225@qq.com', '付款通知异常(weixin_h5)', 'order_info is empty'.$order_id);
                    exit('fail');
                }

                // 订单已取消
                if($order_info['progress'] == 0) {
                    mail_helper::mail('353182225@qq.com', '付款通知异常(weixin_h5)', '订单已取消，不能再支付'.$order_id);
                    exit('fail');
                }

                // 已经支付，无需再次支付
                if($order_info['progress'] == 10) {
                    //mail_helper::mail('353182225@qq.com', '付款通知异常(weixin_h5)', '订单'.$order_id.'已经支付，无需再次支付');
                    exit('fail');
                }

                // 不是待支付状态
                if($order_info['progress'] != 1) {
                    mail_helper::mail('353182225@qq.com', '付款通知异常(weixin_h5)', 'order_status  is not eq 1'.$order_id);
                    exit('fail');
                }

                // 订单被删除
                if($order_info['status'] == 0) {
                    mail_helper::mail('353182225@qq.com', '付款通知异常(weixin_h5)', '订单已被删除'.$order_id);
                    exit('fail');
                }

                // if (!ONDEV) {
                //     // 检查支付金额是否和订单金额一致
                //     if($order_info['price']*100 != $price) {
                //         mail_helper::mail('353182225@qq.com', '付款通知异常(weixin_h5)', '支付金额是否和订单金额不一致'.$order_id);
                //         exit('fail');
                //     }
                // }

                //mail_helper::mail('245629560@qq.com', 'order_id', $order_id);exit;

                // 更新订单
                _model('order')->update($order_id, array(
                    'progress'   => 10,
                    'pay_time' => $finish_time,
                    'transaction_id' => $notify->data['transaction_id'],
                    'pay_type' => 2
                ));
                // mail_helper::mail('353182225@qq.com', 'wx_pay_log信息1', '1111');
                $wx_pay_log = array(
                        'order_id'       => $order_id,
                        'openid'         => $notify->data['openid'],
                        'price'          => $price/100,
                        'data'           => serialize($notify->data),
                        'transaction_id' => $notify->data['transaction_id'],
                        'trade_type'     => $notify->data['trade_type'],
                        'ip'             => Request::getClientIp()
                );

                //mail_helper::mail('245629560@qq.com', 'wx_pay_log信息', var_export($wx_pay_log, true));

                if(!_uri('wx_pay_log', array('order_id' => $order_id))){
                    _model('wx_pay_log')->create($wx_pay_log);
                }
                //增加销量
                order_helper::add_sale_num($order_id);
                //同步到BTCP
                _widget('erp_lenovo.erp_lenovo_order')->AddOrder($order_id);
                
                // mail_helper::mail('353182225@qq.com', 'wx_pay_log信息2', var_export($wx_pay_log, true));
                // 下发短信
                //vocher_helper::send_vocher($order_no);

                // 下发邮件
                //order_helper::pay_email_v2('付款通知(weixin_h5)', $order_no, $finish_time);

                // 下发通知

                // weixin_helper::send_notify_info($order_id);

                // 增加统计
                // _widget('stat.trade_stat')->trade_stat(1000, $order_info['shop_id'], $price);

                // 设置返回码
                $notify->setReturnParameter("return_code","SUCCESS");

            }

        } else {

            // 签名失败

            // 返回状态码
            $notify->setReturnParameter("return_code","FAIL");

            // 返回信息
            $notify->setReturnParameter("return_msg","签名失败");
        }

        // 返回微信参数
        $returnXml = $notify->returnXml();
        echo $returnXml;

    }


    /**
     * 付款通知
     * @param unknown_type $user_id  用户ID
     * @param unknown_type $goods_name  商品名称
     * @param unknown_type $price     商品价格
     * @param unknown_type $order_no  订单号
     * @param unknown_type $code      电子码
     * @param unknown_type $remark
     */
    public function send_notify_info($user_id, $goods_name, $price, $order_no, $code, $remark)
    {
        weixin_helper::send_notify_info($order_no);

    }


}
?>